
"""
对接 zstack-api管理接口
规则：
    1. 查看操作： get_*
    2. 创建操作： create_*
    3. 删除操作： del_*
    4. 加载操作： attach_*
    5. 卸载操作： detach_*

"""
import sys
from urllib.parse import quote
from flask import current_app, request
from tools.zstack_cloud import ZStackCloud
from app.common.base_manager import BaseManager

class ZStackManager():

    def __init__(self):
        self.zstack_cloud = ZStackCloud()

    # =================== 镜像相关 ============================

    def get_images(self, image_uuid):
        """获取镜像详细信息"""
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url=f"images/{image_uuid}")

    def crteate_images_server(self):
        """创建镜像服务器"""
        pass

    def create_image(self, name, file_url, resource_uuid, backup_storage_uuids: list, image_type, os_type="Linux", **kwargs):
        """创建镜像"""
        data = {
            "params": {
                "name": name,
                "url": file_url,
                "platform": os_type,
                "format": image_type,
                "backupStorageUuids": backup_storage_uuids,
                "resourceUuid": resource_uuid
            }
        }
        print(data)
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="images", data=data, **kwargs) 
     
    def get_image_list(self, limit=None, page_size=None):
        """获取镜像列表

        Args:
            limit (_type_, optional): 页面. Defaults to None.
            page_size (_type_, optional): 每页数量. Defaults to None.
        """
        
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url="images")
    
    def del_image_destroy(self, image_uuid, del_model="Permissive", **kwargs):
        """删除镜像"""
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"images/{image_uuid}?deleteMode={del_model}", **kwargs)
    
    def del_image_expunge(self, image_uuid, **kwargs):
        """彻底删除镜像"""
        
        data = {
            "expungeImage": {}
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="put", url=f"images/{image_uuid}/actions", data=data, **kwargs)
      
    # =================== 云主机 ============================
        
    def get_vm_list(
            self,
            marker=None,
            limit=None, 
            sort_key=None,
            sort_dir=None,
            all_projects=False,
            **kwargs):
        """获取全部云主机列表

        Args:
            marker (_type_, optional): 主机UUID,配合limit分页. Defaults to None.
            limit (_type_, optional): None时返回zun api限制最大值，>0时返回对应数量. Defaults to None.
            sort_key (_type_, optional): 排序字段. Defaults to None.
            sort_dir (_type_, optional): 排序方式 'asc' (默认) 或 'desc'. Defaults to asc.
            all_projects (bool, optional): 从全部项目中获取. Defaults to False.
        kwargs:
          - name: 按名称
          - image: 按镜像
          - project_id: 按项目ID
          - user_id: 按用户ID
          - memory: 按 Mib 中的内存大小过滤响应
          - host: 按主机名过滤响应，作为字符串
          - task_state: 按任务状态过滤响应
          - status: 按容器的当前状态过滤响应
          - auto_remove: boolean: 根据响应是否在退出时自动删除来过滤响应
        """
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url="vm-instances")
        
    def get_vm_details(self, vm_uuid):
        """获取云主机详细信息

        Args:
            vm_uuid (_type_): _description_
        """
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url=f"vm-instances/{vm_uuid}")
    
    def create_vm(self, name, instance_offering_uuid, image_uuid, l3Network_uuids, dataDisk_offering_uuids, resource_uuid, systemTags=None,  default_l3_network_uuid=None, strategy="InstantStart", **kwargs):
        """创建云主机

        Args:
            name (_type_): _description_
            instanceOfferingUuid (_type_): _description_
            imageUuid (_type_): _description_
            l3NetworkUuids (_type_): _description_
            dataDiskOfferingUuids (_type_): _description_
            description (_type_): _description_
            strategy (_type_): _description_
            systemTags (_type_): _description_  ["vmConsoleMode::vnc","consolePassword::root", "hostname::abc"]

        Returns:
            _type_: _description_
        """
        if systemTags is None:
            systemTags = []
        data = {
            "params": {
                "name": name,
                "instanceOfferingUuid": instance_offering_uuid,
                "imageUuid": image_uuid,
                "l3NetworkUuids": l3Network_uuids,
                "dataDiskOfferingUuids": dataDisk_offering_uuids,
                "strategy": strategy,
                "resourceUuid": resource_uuid
            },
            "systemTags": systemTags
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        if default_l3_network_uuid:
            data["params"]["defaultL3NetworkUuid"] = default_l3_network_uuid
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="vm-instances", data=data, **kwargs)
  
    def start_vm(self, vm_uuid, **kwargs):
        """启动一个云主机, 异步

        Args:
            vm_uuid (_type_): _description_
        """
        data = {
            "startVmInstance": {}
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="put", url=f"vm-instances/{vm_uuid}/actions", data=data, **kwargs)
    
    def stop_vm(self, vm_uuid, shutdown="grace", **kwargs):
        """停止一个云主机，异步

        Args:
            uuid (_type_): 云主机uuid
            shutdown (_type_): 云主机关机方式
        """
        data = {
            "stopVmInstance": {
                "type": shutdown
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="put", url=f"vm-instances/{vm_uuid}/actions", data=data, **kwargs)
        
    def del_vm_destroy(self, vm_uuid, del_model="Permissive", **kwargs):
        """删除云主机、路由器，先删除再彻底删除, 删除也会删除相关网卡、云盘、光驱等资源
           

        Args:
            uuid (_type_): _description_
            del_model (_type_): 删除方式， permissive  Enforcing: 强制删除
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"vm-instances/{vm_uuid}?deleteMode={del_model}", **kwargs)

    def del_vm_expunge(self, vm_uuid, **kwargs):
        """彻底删除vm

        Args:
            vm_uuid (_type_): _description_
        """
        data = {
            "expungeVmInstance": {}
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with  self.zstack_cloud as zsclient:
            return zsclient(method="put", url=f"vm-instances/{vm_uuid}/actions", data=data, **kwargs)
        
    def get_vm_network(self, vm_uuid):
        """获取指定云主机网络列表, TODO:返回空？？

        Args:
            uuid (_type_): _description_
        """
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url=f"vm-instances/nics/{vm_uuid}")
        
    def detach_l3_network_vm(self, vm_network_id, **kwargs):
        """云主机卸载网络

        Args:
            vm_network_id (_type_, optional): _description_. Defaults to None.
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"vm-instances/nics/{vm_network_id}", **kwargs)

    def get_vm_console_address(self, vm_uuid, **kwargs):
        """获取云主机控制台地址和访问协议, 云主机必须在开机状态

        Args:
            vm_uuid (_type_): _description_
        """
        data = {
            "params": {
                "vmInstanceUuid": vm_uuid
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="consoles", data=data, **kwargs)
    
    # ===============云主机规格===========================
     
    def get_flavors(self):
        """查询云主机规格列表
        """
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url="instance-offerings")
    
    def get_flavors_details(self, flavor_uuid):
        """获取云主机规格详情

        Args:
            flavor_uuid (_type_): _description_
        """
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url=f"instance-offerings/{flavor_uuid}")
         
    # ===============三层网络=============================
         
    def get_l3_network(self, l3_network=None):
        """查询三层网络: 公有、扁平、vpc

        Args:
            vm_uuid (_type_): _description_
        """
        url = f"l3-networks/{l3_network}" if l3_network else "l3-networks"
        params = {
            "type": "L3VpcNetwork"
        }
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url=url, params=params)

    def attach_l3_network_vm(self, vm_uuid, l3_network_id, driverType="virtio", staticIp=None):
        """加载L3网络到云主机
        
        Args:
            l3_network_id (_type_): 三层网络uid
            staticIp (_type_): 指定分配给云主机的ip地址
            driverType (_type_): 网卡驱动
        """
        data = {
            "params": {
                "driverType": driverType,
                "staticIp": staticIp
            }
        }
        
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"vm-instances/{vm_uuid}/l3-networks/{l3_network_id}", data=data)
                  
    def create_vm_nic(self, network_uid, resource_uuid, ip=None, **kwargs):
        """创建虚拟化网卡

        Args:
            network_uid (_type_): 三层网络uid
        """
        data = {
            "params": {
                "l3NetworkUuid": network_uid,
                "ip": ip,
                "resourceUuid": resource_uuid,
                "resourceTypes": ["VM"]
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        print(data)
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="nics", data=data, **kwargs)

    def del_vm_nic(self, network_nic_uuid, **kwargs):
        """卸载虚拟网卡-(卸载vpc路由)

        Args:
            network_nic_uuid (_type_): _description_
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"nics/{network_nic_uuid}", **kwargs)

    def attach_vm_nic_vm(self, uuid, vm_uuid, **kwargs):
        """加载虚拟网卡到云主机

        Args:
            vm_uuid (_type_): _description_
            nic_uuid (_type_): _description_
        """
        
        data = {
            "params": {}
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"vm-instances/{vm_uuid}/nices/{uuid}", data=data, **kwargs)
    
    # def get_l3_network(self, subnet_uuid, **kwargs):
    #     """获取交换机

    #     Args:
    #         subnet_uuid (_type_): _description_
    #     """
        
    #     with self.zstack_cloud as zsclient:
    #         return zsclient(method="get", url=f"l3-networks/{subnet_uuid}")
        
    def create_l3_network(self, l2_network_uuid, name, resource_uuid, type="L3VpcNetwork", category="Private", system="false", ipVersion="4", **kwargs):
        """创建三层网络

        Args:
            l2_network_uuid (_type_): 二层网络uuid
            name (_type_): 网络名称
            resourceUuid (_type_): 三层网络uuid,因回调所以必须指定
            type (str, optional): 网络类型 Defaults to "L3VpcNetwork".
            category (str, optional): _description_. Defaults to "Private".
            system (str, optional): _description_. Defaults to "false".
            ipVersion (str, optional): 标准 Defaults to "4".

        Returns:
            _type_: _description_
        """
        data = {
            "params": {
                "name": name,
                "type": "L3VpcNetwork",
                "l2NetworkUuid": l2_network_uuid,
                "category": "Private",
                "system": system,
                "ipVersion": ipVersion, 
                "resourceUuid": resource_uuid
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="l3-networks", data=data, **kwargs)

    def create_l3_network_ip_ranges(self, l3_network_uuid, network_cidr, ip_version=4, **kwargs):
        """创建网络的ip范围

        Args:
            l3_network_uuid (_type_): _description_
            network_cidr (_type_): _description_
            ip_version (int, optional): _description_. Defaults to 4.

        Returns:
            _type_: _description_
        """
        data = {
            "params": {
                "name": network_cidr,
                "networkCidr": network_cidr,
                "ipVersion": ip_version
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"l3-networks/{l3_network_uuid}/ip-ranges/by-cidr", data=data, **kwargs)
 
    def attach_network_service_to_l3Network(self, l3_network_uuid, network_service, **kwargs):
        """挂载网络服务到三层网络

        Args:
            l3_network_uuid (_type_): _description_

        Returns:
            _type_: _description_
        """
        data = {
            "params": {
                "networkServices": network_service
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"l3-networks/{l3_network_uuid}/network-services", data=data, **kwargs)
        
    def detach_network_service_from_l3_network(self, l3_network_uuid, network_services, **kwargs):
        """从三层网络卸载网络服务

        Args:
            l3_network_uuid (_type_): _description_
            network_services (_type_): _description_
        """
        
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"l3-networks/{l3_network_uuid}/network-services?networkServices={network_services}")
        
    def del_l3_network(self, l3_network_uuid, delete_mode="Permissive", **kwargs):
        """删除三层网络

        Args:
            l3_network_uuid (_type_): _description_
            delete_mode (str, optional): _description_. Defaults to "Permissive".

        Returns:
            _type_: _description_
        """
        print(kwargs)
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"l3-networks/{l3_network_uuid}?deleteMode={delete_mode}", **kwargs)

    def add_dns_to_l3_network(self, l3_network_id, dns, **kwargs):
        """向三层网络添加dns

        Args:
            l3_network_id (_type_): _description_
            dns (_type_, optional): _description_

        Returns:
            _type_: _description_
        """
        data = {
            "params": {
                "dns": dns
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"l3-networks/{l3_network_id}/dns", data=data, **kwargs)

    # =================安全组========================
        
    def create_security_group(self, name, resource_uuid, description=None, ip_version=4, **kwargs):
        """创建安全组

        Args:
            name (_type_): _description_
            description (_type_, optional): _description_. Defaults to None.
            ipVersion (int, optional): _description_. Defaults to 4.
            resourceUuid (_type_, optional): _description_. Defaults to None.
        """
        data = {
            "params": {
                "name": name,
                "description": description,
                "ipVersion": ip_version,
                "resourceUuid": resource_uuid
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="security-groups", data=data, **kwargs)

    def del_security_group(self, security_group_uuid, del_model="Permissive", **kwargs):
        """删除安全组

        Args:
            security_group_uuid (_type_): _description_
            del_model (str, optional): _description_. Defaults to "Permissive".
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"security-groups/{security_group_uuid}?deleteMode={del_model}", **kwargs)
    
    def get_security_group(self, security_group_uuid=None):
        """查询安全组, 支持单个和所有

        Args:
            security_group_uuid (_type_): _description_
        """
        with self.zstack_cloud as zsclient:
            url = (
                f"security-groups/{security_group_uuid}"
                if security_group_uuid
                else "security-groups"
            )
            return zsclient(method="get", url=url)
          
    def attach_vm_nic_security_group(self, security_group_uuid, vm_nic_uuids, **kwargs):
        """添加虚拟网卡到安全组

        Args:
            security_group_uuid (_type_): _description_
            vm_nic_uuids (_type_): _description_
        """
        data = {
            "params": {
                "vmNicUuids": vm_nic_uuids
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"security-groups/{security_group_uuid}/vm-instances/nics", data=data, **kwargs)
    
    def attach_security_group_l3_network(self, security_group_uuid, l3_network_uuid, **kwargs):
        """挂载安全组到l3网络

        Args:
            security_group_uuid (_type_): _description_
            l3_network_uuid (_type_): _description_
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"security-groups/{security_group_uuid}/l3-networks/{l3_network_uuid}", **kwargs)
    
    def detach_security_group_l3_network(self, security_group_uuid, l3_network_uuid):
        """l3网络卸载安全组

        Args:
            security_group_uuid (_type_): _description_
            l3_network_uuid (_type_): _description_
        """
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"security-groups/{security_group_uuid}/l3-networks/{l3_network_uuid}")
        
    def attach_security_group_rule(self, security_group_uuid, rules, remote_security_group_uuid=None, **kwargs):
        """添加规则到安全组

        Args:
            security_group_uuid (_type_): _description_
            rules (_type_): _description_
            remote_security_group_uuids (list, optional): _description_. Defaults to [].
        """
        if remote_security_group_uuid is None:
            remote_security_group_uuid = []
        data = {
            "params": {
                "rules": rules,
                "remoteSecurityGroupUuids": remote_security_group_uuid
            }
        }

        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"security-groups/{security_group_uuid}/rules", data=data, **kwargs)
        
    def get_security_group_rule(self, security_group_uuid, **kwargs):
        """查询安全组规则

        Args:
            security_group_uuid (_type_): _description_
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url=f"security-groups/rules/{security_group_uuid}", **kwargs)
        
    def del_security_group_rule(self, rule_uuid, **kwargs):
        """删除安全组规则

        Args:
            rule_uuid (_type_): _description_
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"security-groups/rules?ruleUuids={rule_uuid}", **kwargs)
    
    # ============= 资源监控 =======================
    def sget_host_list(self, host_uuid=None):
        """查询物理机信息， 可指定查询

        Args:
            host_uuid (_type_): _description_ 
        """
        
        with self.zstack_cloud as  zsclient:
            url = f"/hosts/{host_uuid}" if host_uuid else "hosts"
            return zsclient(method="get", url=url)
        
    # ===================== 二层网络 ============================
    def get_l2_vxlan_network_pool(self, **kwargs):
        """查询vxlan网络池
        """
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url="l2-networks/vxlan-pool/vni-range", **kwargs)
        
    
    def create_l2_vxlan_network_pool(self, name, zone_uuid, resource_uuid, **kwargs):
        """创建vxlan网络池,无法加载到集群

        Args:
            name (_type_): _description_
            zone_uuid (_type_): _description_
        """
        data = {
            "params": {
                "name": name,
                "zoneUuid": zone_uuid,
                "resourceUuid": resource_uuid,
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="l2-networks/vxlan-pool", data=data, **kwargs)
        
    def create_vni_range(self, l2_network_uuid, name, start_vni, end_vni, resource_uuid, **kwargs):
        """创建VNI  Range

        Args:
            l2_network_uuid (_type_): _description_
            name (_type_): _description_
            start_vni (_type_): _description_
            end_vni (_type_): _description_
            resource_uuid (_type_): _description_
        """
        data = {
            "params": {
                "name": name,
                "startVni": start_vni,
                "endVni": end_vni,
                "resourceUuid": resource_uuid
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"l2-networks/vxlan-pool/{l2_network_uuid}/vni-ranges", data=data, **kwargs)
        
    def attach_l2_network_to_cluster(self, l2_network_uuid, cluster_uuid, cidr, **kwargs):
        """挂载二层网络到集群

        Args:
            l2_network_uuid (_type_): _description_
            cluster_uuid (_type_): _description_
        """
        data = {
            "systemTags": [f"l2NetworkUuid::{l2_network_uuid}::clusterUuid::{cluster_uuid}::cidr::\u007b{cidr}\u007d"]
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"l2-networks/{l2_network_uuid}/clusters/{cluster_uuid}", data=data, **kwargs)
        
    def detach_l2_network_from_cluster(self, l2_network_uuid, cluster_uuid, **kwargs):
        """从集群卸载二层网络

        Args:
            l2_network_uuid (_type_): _description_
            cluster_uuid (_type_): _description_
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"l2-networks/{l2_network_uuid}/clusters/{cluster_uuid}", **kwargs)
    
    def create_l2_vxlan_network(self, pool_uuid, name, zone_uuid, resource_uuid, **kwargs):
        """创建二层vxlan网络

        Args:
            pool_uuid (_type_): _description_
            name (_type_): _description_
            zone_uuid (_type_): _description_
        """
        data = {
            "params": {
                "poolUuid": pool_uuid,
                "name": name,
                "zoneUuid": zone_uuid,
                "resourceUuid": resource_uuid
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="l2-networks/vxlan", data=data, **kwargs)
    
    def del_l2_network(self, network_id,  del_model="Permissive", **kwargs):
        """删除二层网络

        Args:
            vxlan_pool_uuid (_type_): _description_
            del_model (str, optional): _description_. Defaults to "Permissive".

        Returns:
            _type_: _description_
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"l2-networks/{network_id}?deleteMode={del_model}", **kwargs)
    
    # ==================== VPC路由 =================================
    def create_vpc_router(self, name, router_offering_uuid, resource_uuid, **kwargs):
        """创建vpc路由

        Args:
            name (_type_): _description_
            router_offering_uuid (_type_): _description_
            resource_uuid (_type_): _description_
        """
        data = {
            "params": {
                "name": name,
                "virtualRouterOfferingUuid": router_offering_uuid,
                "resourceUuid": resource_uuid
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="vpc/virtual-routers", data=data, **kwargs)
    
    def attach_l3network_route(self, route_uuid, l3_network_uuid, **kwargs):
        """加载vpc网络至vpc路由器

        Args:
            route_uuid (_type_): _description_
            l3_network_uuid (_type_): _description_
        """
        data = {
            "params": {
                "driverType":"virtio"
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"vm-instances/{route_uuid}/l3-networks/{l3_network_uuid}", data=data, **kwargs)
    
    # ==================== 基础网络服务 =================================
    def create_vip_action(self, name, l3_network_uuid, resource_uuid, **kwargs):
        """创建虚拟IP

        Args:
            l3_network_uuid (_type_): _description_
        """
        data = {
            "params": {
                "name": name, 
                "l3NetworkUuid": l3_network_uuid,
                "resourceUuid": resource_uuid
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="vips", data=data, **kwargs)
        
    def create_eip_action(self, name, vip_uuid, resource_uuid, **kwargs):
        """创建弹性IP

        Args:
            name (_type_): _description_
            vip_uuid (_type_): _description_
        """
        data = {
            "params": {
                "name": name,
                "vipUuid": vip_uuid,
                "resourceUuid": resource_uuid
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="eips", data=data, **kwargs)
        
    def attach_eip_to_vm(self, eip_uuid, vm_nic_uuid, **kwargs):
        """绑定弹性IP

        Args:
            eip_uuid (_type_): _description_
            vm_nic_uuid (_type_): _description_
        """
        data = {
            "params": {}
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url=f"eips/{eip_uuid}/vm-instances/nics/{vm_nic_uuid}", data=data, **kwargs)
   
    def del_vips_ip(self, vip_uuid, **kwargs):
        """删除虚拟ip
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"vips/{vip_uuid}?", **kwargs)

    
    # ====================== 端口镜像 ============================
    def create_port_mirror(self, mirror_network_uuid, name, resource_uuid,state_event="enable", **kwargs):
        """创建端口镜像

        Returns:
            _type_: _description_
        """
        data = {
            "params": {
                "mirrorNetworkUuid": mirror_network_uuid,
                "name": name,
                "stateEvent": state_event,
                "resourceUuid": resource_uuid,
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="port-mirrors", data=data, **kwargs)
        
    def create_port_mirror_session(self, port_mirror_uuid, name, src_end_point, dst_end_point, resource_uuid, **kwargs):
        """创建端口镜像会话

        Returns:
            _type_: _description_
        """
        data = {
            "params": {
                "portMirrorUuid": port_mirror_uuid,
                "name": name,
                "type": "Ingress",
                "srcEndPoint": src_end_point,
                "dstEndPoint": dst_end_point,
                "resourceUuid": resource_uuid
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        print(data)
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="port-mirrors/sessions", data=data, **kwargs)
    
    def del_port_mirror(self, mirror_uuid, **kwargs):
        """删除端口镜像

        Returns:
            _type_: _description_
        """
        with self.zstack_cloud as zsclent:
            return zsclent(method="delete", url=f"port-mirrors/{mirror_uuid}", **kwargs)
        
    def del_port_mirror_session(self, mirror_session_uuid, **kwargs):
        """删除端口镜像会话

        Args:
            mirror_session_uuid (_type_): _description_

        Returns:
            _type_: _description_
        """
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"port-mirrors/sessons/{mirror_session_uuid}", **kwargs)
    
    # ====================== 云主机监控 ============================
    def get_vm_metric(self, vm_uuid, metricName, startTime, endTime, **kwargs):
        """获取云主机监控信息,CPU,磁盘、内存等实时监控数据:

        Args:
            metricName{
            CPU
            DISK
            MEM
            }
        """
        data = {
            "params": {

            }
        }
        if metricName == 'MEM':
            ZQL = f"""query VmInstance.uuid where uuid='{vm_uuid}'
                    return with (total, zwatch {{resultName='zwatch0',namespace='ZStack/VM',
                    metricName='MemoryUsedBytes',
                    startTime={startTime},
                    endTime={endTime},period=60, labels='VMUuid={vm_uuid}'}})
                """
        elif metricName == "CPU":
            ZQL = f"""query VmInstance.uuid where uuid='{vm_uuid}' 
            return with (total, zwatch {{resultName='zwatch0',namespace='ZStack/VM', 
            metricName='CPUAverageUsedUtilization',
            startTime={startTime}, 
            endTime={endTime},period=60,labels='VMUuid={vm_uuid}'}})
                """
        elif metricName == 'DISK':
            ZQL = f"""query VmInstance.uuid where uuid='{vm_uuid}'
                    return with (total, zwatch {{resultName='zwatch0',namespace='ZStack/VM',
                    metricName='DiskReadBytes',
                    startTime={startTime},
                    endTime={endTime},period=60,
                    labels='VMUuid={vm_uuid}',
                    labels='DiskDeviceLetter=~vda'}})
                """
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url=f"zql?zql={quote(ZQL)}", data=data, **kwargs)


        ###########################监控系统信息#######################################
    def get_host_monitor(self, type, startTime='', endTime=''):
        """获取云主机监控信息，CPU，磁盘、内存等实时监控数据；

        Args:
            type{
               vmInstanceCount
               CPU_MEM_DISK
               }
        """
        data = {
            "params": {

            }
        }
        if type == 'vmInstanceCount':
            # 虚机运行总数；
            ZQL = "query vmInstance.state where (type='UserVm' and hypervisorType!='ESX' and state!='Destroyed' and type!='VCenter' and zone.uuid='9f42b28a1fec4770b2221ad2de12d3ea')"

        if type == "host":
            ZQL = f"""query host  where (hypervisorType!='ESX' and hypervisorType!='baremetal2' and zoneUuid='9f42b28a1fec4770b2221ad2de12d3ea') return with (total) order by createDate desc limit 10           
            """

        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url=f"zql?zql={quote(ZQL)}", data=data)

    def get_cpu_memory(self):
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url=f"hosts/capacities/cpu-memory?zoneUuids={self.zstack_cloud.zone_uuid}")

    def get_storage(self):
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url=f"primary-storage")

    def get_vm_max_rate_info(self):
        max_rate = {}
        # 获取主存储
        storage_info = self.get_storage()
        totalCapacity = storage_info[0]['totalCapacity'] #总空间
        availableCapacity = storage_info[0]['availableCapacity'] #总空间
        storage_total = round(totalCapacity / 1024 / 1024 / 1024 / 1024)
        storage_used = round((totalCapacity-availableCapacity) / 1024 / 1024 / 1024 / 1024)
        storage_dict = {"maxInstances": storage_total, "usedInstances": storage_used}
        max_rate['instance'] = storage_dict

        #cpu 和内存
        cpu_memory_info = self.get_cpu_memory()
        totalCpu = cpu_memory_info['totalCpu']
        usedCup = cpu_memory_info['totalCpu'] - cpu_memory_info['availableCpu']
        cpu_dict = {"maxCores": totalCpu, "usedCores": usedCup}
        max_rate['vcpu'] = cpu_dict
        #内存分配率
        totalMemory=cpu_memory_info['totalMemory']
        usedMemory= cpu_memory_info['availableMemory']
        memory_size = round(totalMemory / 1024 / 1024)
        memory_used = round((totalMemory-usedMemory) / 1024 / 1024)
        memory_dict = {"maxMem": memory_size, "usedMem": memory_used}
        max_rate['mem'] = memory_dict
        return max_rate


    # ==================== 资源栈 =========================
    def create_resource_stack(self, name, resource_uuid, parameters=None, template_content=None, template_uuid=None, type="zstack",  **kwargs):
        """创建资源栈

        Args:
            name (_type_): _description_
            template_content (_type_): _description_
            resource_uuid (_type_): _description_
            parameters (_type_): _description_
            template_uuid (_type_): _description_
            type (str, optional): _description_. Defaults to "zstack".
            rollback (bool, optional): _description_. Defaults to True.

        Returns:
            _type_: _description_
        """
        if parameters is None:
            parameters = {}
        # template_content 与  template_uuid二选一

        data = {
            "params": {
                "name": name,
                "resourceUuid": resource_uuid,
                "type": type,
                # "parameters": parameters
            }
        }

        if template_content:
            data["params"]["templateContent"] = template_content
        elif template_uuid:
            data["params"]["templateUuid"] = template_uuid

        kwargs["operate"] = sys._getframe().f_code.co_name
        print(data)
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="cloudformation/stack", data=data, **kwargs)
    
    def add_stack_template(self, name, template_content, resource_uuid, type="zstack", **kwargs):
        """添加模板资源

        Args:
            name (_type_): _description_
            template_content (_type_): _description_
            resource_uuid (_type_): _description_
            type (str, optional): _description_. Defaults to "zstack".
        """
        
        data = {
            "params": {
                "name": name,
                "templateContent": template_content,
                "resourceUuid": resource_uuid,
                "type": type
            }
        }
        kwargs["operate"] = sys._getframe().f_code.co_name
        
        with self.zstack_cloud as zsclient:
            return zsclient(method="post", url="cloudformation/template", data=data, **kwargs)
        
    def del_stack_template(self, stack_uuid, **kwargs):
        """删除资源栈模板

        Args:
            stack_uuid (_type_): _description_
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"cloudformation/template/{stack_uuid}", **kwargs)
        
    def get_resource_from_resource_stack(self, resource_uuid, **kwargs):
        """获取资源栈内资源列表(二层、三层、云主机、路由器)

        Args:
            stack_uuid (_type_): _description_
        """
        
        with self.zstack_cloud as zsclient:
            return zsclient(method="get", url=f"cloudformation/stack/resources?uuid={resource_uuid}", **kwargs)

    def del_resource_stack(self, stack_uuid,  **kwargs):
        """删除资源栈

        Args:
            stack_uuid (_type_): _description_
        """
        kwargs["operate"] = sys._getframe().f_code.co_name
        with self.zstack_cloud as zsclient:
            return zsclient(method="delete", url=f"cloudformation/stack/{stack_uuid}", **kwargs)
    
    # ===============云主机规格===========================
    
if __name__ == "__main__":
    
    zstack_manager = ZStackManager()
    print(zstack_manager.get_container_list())
